package com.ld.shieldsb.common.core.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

import lombok.extern.slf4j.Slf4j;

/**
 * java8的日期时间工具类（考虑到coreCredit的共用性，暂时放在具体项目下）
 * 
 * @author lv
 *
 */
@Slf4j
public final class DateTimeUtil {
    public static final DateTimeFormatter DATETIME_FORMATE = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DATE_FORMATE = DateTimeFormatter.ofPattern("uuuu-MM-dd");
    public static final DateTimeFormatter TIME_FORMATE = DateTimeFormatter.ofPattern("HH:mm:ss");

    private DateTimeUtil() {
        super();
    }

    /**
     * 获取uuuu-MM-dd HH:mm:ss格式的时间字符串
     * 
     * @Title getNowDateStr
     * @author 吕凯
     * @date 2016年7月28日 上午8:36:24
     * @return String
     */
    public static String getNowDateTimeStr() {
        return getNowDateTimeStrByFormatter(DATETIME_FORMATE);
    }

    /**
     * 获取uuuu-MM-dd格式的日期字符串
     * 
     * @Title getNowDateStr
     * @author 吕凯
     * @date 2016年7月28日 上午8:36:24
     * @return String
     */
    public static String getNowDateStr() {
        return getNowDateTimeStrByFormatter(DATE_FORMATE);
    }

    /**
     * 
     * 获取HH:mm:ss格式的时间字符串
     * 
     * @Title getNowTimeStr
     * @author 吕凯
     * @date 2016年7月28日 上午8:37:06
     * @return String
     */
    public static String getNowTimeStr() {
        return getNowDateTimeStrByFormatter(TIME_FORMATE);
    }

    /**
     * 
     * 根据传入的格式化对象返回字符串
     * 
     * @Title getNowDateTimeStrByFormatter
     * @author 吕凯
     * @date 2016年7月28日 上午8:37:28
     * @param formatter
     * @return String
     */
    public static String getNowDateTimeStrByFormatter(DateTimeFormatter formatter) {
        LocalDateTime datetime = LocalDateTime.now();
        String str = datetime.format(formatter);
        return str;
    }

    /**
     * 将传入的毫秒数转化为uuuu-MM-dd HH:mm:ss格式的时间字符串
     * 
     * @Title getDateTimeString
     * @author 吕凯
     * @date 2016年7月28日 上午8:37:53
     * @param epochMilli
     * @return String
     */
    public static String getDateTimeString(long epochMilli) {
        Instant instants = Instant.ofEpochMilli(epochMilli);
        LocalDateTime datetime = LocalDateTime.ofInstant(instants, ZoneId.systemDefault());
        return datetime.format(DATETIME_FORMATE);
    }

    /**
     * 
     * uuuu-MM-dd格式的字符串转换为LocalDate
     * 
     * @Title str2date
     * @author 吕凯
     * @date 2016年7月28日 上午8:38:45
     * @param dateStr
     * @return LocalDate
     */
    public static LocalDate str2date(String dateStr) {
        if (dateStr == null) {
            return null;
        }
        try {
            LocalDate date = null;
            try {
                date = LocalDate.parse(dateStr, DATE_FORMATE);
            } catch (Exception e) {
                DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd");
                date = LocalDate.parse(dateStr, f);
            }
            return date;
        } catch (Exception e) {
            log.warn("日期转换错误，dateStr‘" + dateStr + "’，" + e.getMessage());
            return null;
        }
    }

    /**
     * 
     * 获取传入的uuuu-MM-dd格式的字符串转换为所在月份的第一天uuuu-MM-dd HH:mm:ss格式的时间字符串
     * 
     * @Title getMonthFirstTimeStr
     * @author 吕凯
     * @date 2016年7月28日 上午8:39:36
     * @param dateStr
     * @return String
     */
    public static String getMonthFirstTimeStr(String dateStr) {
        if (dateStr == null) {
            return null;
        }
        DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd");
        LocalDate date = LocalDate.parse(dateStr, f);
        return getMonthFirstTimeStr(date);
    }

    public static String getMonthFirstTimeStr(LocalDate date) {
        if (date == null) {
            return null;
        }
        DateTimeFormatter f1 = DateTimeFormatter.ofPattern("uuuu-MM-01");
        return date.format(f1) + " 00:00:00";
    }

    /**
     * 获取传入日期所在0时0分0秒时间
     * 
     * @Title getMonthFirstTime
     * @author 吕凯
     * @date 2016年8月8日 下午2:24:43
     * @param date
     * @return Date
     */
    public static Date getDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取传入日期所在月份的第一天
     * 
     * @Title getMonthFirstTime
     * @author 吕凯
     * @date 2016年8月8日 下午2:24:43
     * @param date
     * @return Date
     */
    public static Date getMonthFirstTime(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static String getMonthLastTimeStr(String dateStr) {
        if (dateStr == null) {
            return null;
        }
        DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd");
        LocalDate date = LocalDate.parse(dateStr, f);
        return getMonthLastTimeStr(date);
    }

    public static String getMonthLastTimeStr(LocalDate date) {
        if (date == null) {
            return null;
        }
        YearMonth creditCardExpiry = YearMonth.of(date.getYear(), date.getMonth());
        DateTimeFormatter f1 = DateTimeFormatter.ofPattern("uuuu-MM-" + creditCardExpiry.lengthOfMonth());
        return date.format(f1) + " 23:59:59";
    }

    /**
     * 
     * 将传入的LocalDateTime对象转换为毫秒数
     * 
     * @Title dateTime2Milli
     * @author 吕凯
     * @date 2016年7月28日 上午8:45:34
     * @param datetime
     * @return long
     */
    public static long dateTime2Milli(LocalDateTime datetime) {
        if (datetime == null) {
            return 0;
        }
        long millis = datetime.toInstant(ZoneOffset.of("+08:00")).toEpochMilli();
        return millis;
    }

    /**
     * 将传入的LocalDate对象转换为毫秒数
     * 
     * @Title dateTime2Milli
     * @author 吕凯
     * @date 2016年7月28日 上午8:45:12
     * @param date
     * @return long
     */
    public static long dateTime2Milli(LocalDate date) {
        if (date == null) {
            return 0;
        }
        long millis = dateTime2Milli(date.atStartOfDay());
        return millis;
    }

    /**
     * 将传入的uuuu-MM-dd HH:mm:ss格式字符串转换为Date
     * 
     * @Title getStr2Date
     * @author 吕凯
     * @date 2016年7月28日 上午8:42:06
     * @param format
     * @return Date
     */
    public static Date str2SqlDate(String dateStr) {
        if (dateStr == null) {
            return null;
        }
        LocalDate date = LocalDate.parse(dateStr, DATETIME_FORMATE);
        return new Date(dateTime2Milli(date));
    }

    /**
     * 
     * 根据传入的格式化字符串格式化传入的日期
     * 
     * @Title getDateStr
     * @author 吕凯
     * @date 2016年7月28日 上午8:42:41
     * @param date
     * @param format
     * @return String
     */
    public static String getDateStr(Date date, String format) {
        if (date == null) {
            return null;
        }
        return new SimpleDateFormat(format).format(date);
    }

    /**
     * 将传入的yyyy-MM-dd格式字符串转换为Date
     * 
     * @Title getStr2Date
     * @author 吕凯
     * @date 2016年7月28日 上午8:42:06
     * @param format
     * @return Date
     */
    public static Date getStr2Date(String format) {
        Date date = null;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(format);
        } catch (ParseException e) {
            log.error("", e);
        }
        return date;
    }

    public static void main(String[] args) {
        long syslong = System.currentTimeMillis();
        System.out.println(getDateTimeString(syslong));
        LocalDate date = LocalDate.now();
        System.out.println(date.toEpochDay());

    }

}
